Vehicle route problem with mixed integer programming by Himanshu Bhardwaj

Problem

There are n customers locations and a depot location. At the customer's locations, there is some delivery and pickup demands. A depot has m vehicles and all the vehicles have capacity C. Rij is the amount of the delivery amount on borad between the nodes i and j and Pij is the pickup amount on board between the nodes i and j. cost for each of the vehicles is $1000 per km. With help of this model following Questions can be answered.

(1) What is the optimum number of vehicles to be used.

(2) What are the optimum route map for each vehicles.

(3) What should be the delivery amount for each vehicles at each of the customer nodes the vehicles visit.

(4) Pick up amount of each vehicles at each nodes the vehicles visit.

cost function

$\sum\limits_{i=0}^n \sum\limits_{j=0}^n d_{ij} x_{ij}$

Constraints

$\sum\limits_{i=0}^n x_{ij} = 1, where, j \in \{1,....n\}$

$\sum\limits_{j=0}^n x_{ji} = 1, where, i \in \{1,....n\} $

$\sum\limits_{i=0}^n R_{ij} - q_{j} = \sum\limits_{i=0}^n R_{ji}, where, j \in \{1,2,...,n\} $

$\sum\limits_{i=0}^n P_{ij} + b_{j} = \sum\limits_{i=0}^n P_{ji}, where, j \in \{1,2,...,n\} $

$\sum\limits_{i=0}^n R_{i0} = 0 $

$\sum\limits_{i=0}^n P_{0i} = 0 $

$R_{ij} + P_{ij} = Cx_{ij} $

$R_{ij} >= 0, P_{ij} >=0 $

$x_{0j} <= number of vehicles $

where,

dij : cost of travel from i to j

qi : delivery demand at node i

bi: pickup demand at node i

C : vehicle capacity

Rij: amount of delivery goods on board between nodes i and j

Pij: amount of pick up goods on board between nodes i and j

In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import gurobipy as g
from gurobipy import GRB
import osmnx as ox
import plotly.graph_objects as pt
import networkx as nx
import pulp
import random
In [2]:
graph = ox.load_graphml('Brooklyn_subset.graphml')
ox.plot_graph(graph, figsize=(12,12))
Out[2]:
(<Figure size 864x864 with 1 Axes>, <AxesSubplot:>)
In [3]:
points = pd.read_csv('del_points.csv')
points.head()
Out[3]:
FID lat long
0 0 40.723230 -73.894257
1 1 40.727532 -73.898784
2 2 40.728932 -73.894291
3 3 40.731175 -73.894352
4 4 40.731210 -73.900218
In [4]:
c = np.random.randint(0,27,12)
customers = points.loc[c]
In [5]:
lat = []
lon = []
for i in range(len(customers)):
    lat.append(customers.iloc[i,1])
    lon.append(customers.iloc[i,2])
In [6]:
latm = np.mean(lat)
lonm = np.mean(lon)

Location of the customers

In [7]:
fig = pt.Figure(pt.Scattermapbox(name='Customers', mode='markers',lat=lat, lon=lon, marker={'size': 10, 'color': 'purple'}))
#fig.add_trace(pt.Scattermapbox(name='center', mode='markers', lat=[latm], lon=[lonm], marker={'size':13, 'color':'red'}))
fig.update_layout(mapbox_style = 'stamen-terrain', mapbox_center_lat = latm, mapbox_center_lon = lonm)
fig.update_layout(margin = {'r':0, 'l':0, 'b':0, 't':0}, mapbox={'center':{'lat':latm, 'lon':lonm}, 'zoom':13})
fig.show()
In [8]:
def get_distance(G, p1, p2):
    n1 = ox.get_nearest_node(G,[p1[0],p1[1]])
    n2 = ox.get_nearest_node(G,[p2[0],p2[1]])
    d = nx.shortest_path_length(G, n1, n2, weight='length')
    return d 
In [9]:
customers = customers.reset_index()
customers = customers.drop(['index', 'FID'], axis=1)
customers
Out[9]:
lat long
0 40.731210 -73.900218
1 40.731029 -73.890509
2 40.734953 -73.881266
3 40.729575 -73.882467
4 40.724970 -73.883536
5 40.719481 -73.875049
6 40.727532 -73.898784
7 40.719481 -73.875049
8 40.732265 -73.877504
9 40.723862 -73.889402
10 40.720536 -73.892897
11 40.710310 -73.875054
In [10]:
import vehicle_model as vm
In [11]:
#calculation of cost matrix
cm = [[vm.get_distance(graph, list(customers.loc[i]), list(customers.loc[j])) 
       for i in range(len(customers))] for j in range(len(customers))]
In [12]:
pd.DataFrame(cm)
Out[12]:
0 1 2 3 4 5 6 7 8 9 10 11
0 0.000 988.691 1981.942 1804.005 2136.643 3050.315 522.317 3050.315 2661.597 1989.790 1664.590 4118.471
1 988.691 0.000 1169.888 953.536 1286.174 2199.846 1258.128 2199.846 1811.128 1224.580 1530.231 3517.671
2 1982.818 1169.888 0.000 871.398 1725.628 2117.708 2221.701 2117.708 1139.651 1664.034 2224.211 3435.533
3 1804.005 953.536 871.398 0.000 1023.063 1246.310 1778.736 1246.310 857.592 1088.870 1649.047 2564.135
4 2587.591 1737.122 1654.984 783.586 0.000 1113.573 2479.438 1113.573 1641.178 1051.491 1611.320 2431.398
5 3050.315 2199.846 2117.708 1246.310 1110.640 0.000 3017.325 0.000 2103.902 1589.378 2149.207 1317.825
6 522.317 1120.232 2092.123 1675.405 1691.983 2805.556 0.000 2805.556 2532.997 1467.473 1142.273 3596.154
7 3050.315 2199.846 2117.708 1246.310 1110.640 0.000 3017.325 0.000 2103.902 1589.378 2149.207 1317.825
8 2633.960 1821.030 651.142 1332.846 2355.909 2579.156 2872.843 2579.156 0.000 2315.176 2875.353 3896.981
9 1784.045 1471.956 1911.410 1336.246 781.966 1895.539 1427.947 1895.539 2193.838 0.000 560.177 2791.119
10 1700.175 1538.647 2358.981 1882.336 1261.148 2022.397 1344.077 2022.397 2739.928 916.150 0.000 2639.493
11 3816.422 3362.429 3280.291 2408.893 2273.223 1162.583 3460.324 1162.583 3266.485 2496.365 2510.370 0.000

generating random delivery and pickup demand at the customer location

In [13]:
demand = np.random.randint(1000,2000,12)
demand[0] = 0
demand
Out[13]:
array([   0, 1551, 1371, 1759, 1454, 1591, 1163, 1491, 1219, 1013, 1716,
       1961])
In [14]:
pickup = np.random.randint(800,1500, 12)
pickup
Out[14]:
array([1209,  866,  867, 1442, 1015,  904, 1272, 1176,  984, 1289,  973,
       1368])
In [15]:
capacityofvehicles = 6000
numberofvehicles = 4
In [16]:
m = vm.solve(cm, demand, pickup,capacityofvehicles, numberofvehicles)
Restricted license - for non-production use only - expires 2022-01-13
Gurobi Optimizer version 9.1.2 build v9.1.2rc0 (win64)
Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 201 rows, 432 columns and 1203 nonzeros
Model fingerprint: 0x7eb1d70a
Variable types: 0 continuous, 432 integer (144 binary)
Coefficient statistics:
  Matrix range     [1e+00, 6e+03]
  Objective range  [5e+02, 4e+03]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 2e+03]
Presolve removed 47 rows and 70 columns
Presolve time: 0.03s
Presolved: 154 rows, 362 columns, 1054 nonzeros
Variable types: 0 continuous, 362 integer (110 binary)
Found heuristic solution: objective 47889.330000

Root relaxation: objective 1.600247e+04, 229 iterations, 0.01 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0 16002.4682    0   15 47889.3300 16002.4682  66.6%     -    0s
     0     0 16542.8669    0   61 47889.3300 16542.8669  65.5%     -    0s
H    0     0                    31327.472000 16542.8669  47.2%     -    0s
     0     0 16639.8955    0   51 31327.4720 16639.8955  46.9%     -    0s
     0     0 16639.8955    0   51 31327.4720 16639.8955  46.9%     -    0s
     0     0 16942.2325    0   65 31327.4720 16942.2325  45.9%     -    0s
H    0     0                    23869.417000 16942.2325  29.0%     -    0s
     0     0 16989.8602    0   80 23869.4170 16989.8602  28.8%     -    0s
     0     0 16989.8602    0   80 23869.4170 16989.8602  28.8%     -    0s
     0     0 17280.1635    0   86 23869.4170 17280.1635  27.6%     -    0s
     0     0 17317.5671    0   90 23869.4170 17317.5671  27.4%     -    0s
     0     0 17319.2742    0   87 23869.4170 17319.2742  27.4%     -    0s
     0     0 17319.4338    0   91 23869.4170 17319.4338  27.4%     -    0s
     0     0 17470.8342    0   84 23869.4170 17470.8342  26.8%     -    0s
H    0     0                    23619.153000 17470.8342  26.0%     -    0s
     0     0 17486.6750    0   80 23619.1530 17486.6750  26.0%     -    0s
     0     0 17487.0559    0   84 23619.1530 17487.0559  26.0%     -    0s
     0     0 17504.8932    0   81 23619.1530 17504.8932  25.9%     -    0s
H    0     0                    23533.894000 17504.8932  25.6%     -    0s
     0     0 17507.3588    0   83 23533.8940 17507.3588  25.6%     -    0s
     0     0 17507.7387    0   97 23533.8940 17507.7387  25.6%     -    0s
     0     0 17538.8379    0   81 23533.8940 17538.8379  25.5%     -    0s
     0     0 17539.2248    0   87 23533.8940 17539.2248  25.5%     -    0s
     0     0 17557.4600    0   90 23533.8940 17557.4600  25.4%     -    0s
H    0     0                    19233.046000 17557.4600  8.71%     -    0s
     0     0 17563.4966    0   95 19233.0460 17563.4966  8.68%     -    0s
     0     0 17564.3660    0   95 19233.0460 17564.3660  8.68%     -    0s
     0     0 17581.5699    0   98 19233.0460 17581.5699  8.59%     -    0s
     0     0 17584.8216    0  102 19233.0460 17584.8216  8.57%     -    0s
     0     0 17585.1395    0  105 19233.0460 17585.1395  8.57%     -    0s
     0     0 17588.9516    0  107 19233.0460 17588.9516  8.55%     -    0s
     0     0 17588.9516    0  106 19233.0460 17588.9516  8.55%     -    0s
H    0     0                    19144.484000 17588.9516  8.13%     -    0s
     0     2 17588.9516    0  105 19144.4840 17588.9516  8.13%     -    0s

Cutting planes:
  Gomory: 3
  Cover: 13
  Implied bound: 143
  MIR: 117
  StrongCG: 3
  Flow cover: 22
  Flow path: 5
  Network: 4

Explored 1713 nodes (40280 simplex iterations) in 2.46 seconds
Thread count was 4 (of 4 available processors)

Solution count 7: 19144.5 19233 23533.9 ... 47889.3

Optimal solution found (tolerance 1.00e-04)
Best objective 1.914448400000e+04, best bound 1.914448400000e+04, gap 0.0000%
None
In [17]:
print(m.ObjVal)
19144.484
In [18]:
for v in m.getVars():
    print(v.varname,"=",v.x)
x|0,0 = 1.0
r|0,0 = -0.0
z|0,0 = -0.0
x|0,1 = 1.0
r|0,1 = 5900.0
z|0,1 = -0.0
x|0,2 = 0.0
r|0,2 = -0.0
z|0,2 = -0.0
x|0,3 = 0.0
r|0,3 = -0.0
z|0,3 = -0.0
x|0,4 = 0.0
r|0,4 = -0.0
z|0,4 = -0.0
x|0,5 = 0.0
r|0,5 = -0.0
z|0,5 = -0.0
x|0,6 = 1.0
r|0,6 = 5346.0
z|0,6 = -0.0
x|0,7 = 1.0
r|0,7 = 5043.0
z|0,7 = -0.0
x|0,8 = 0.0
r|0,8 = -0.0
z|0,8 = -0.0
x|0,9 = 0.0
r|0,9 = -0.0
z|0,9 = -0.0
x|0,10 = 0.0
r|0,10 = -0.0
z|0,10 = -0.0
x|0,11 = 0.0
r|0,11 = -0.0
z|0,11 = 0.0
x|1,0 = 0.0
r|1,0 = 0.0
z|1,0 = -0.0
x|1,1 = 0.0
r|1,1 = -0.0
z|1,1 = -0.0
x|1,2 = -0.0
r|1,2 = -0.0
z|1,2 = -0.0
x|1,3 = 1.0
r|1,3 = 4349.0
z|1,3 = 866.0
x|1,4 = -0.0
r|1,4 = -0.0
z|1,4 = -0.0
x|1,5 = -0.0
r|1,5 = -0.0
z|1,5 = -0.0
x|1,6 = -0.0
r|1,6 = -0.0
z|1,6 = -0.0
x|1,7 = -0.0
r|1,7 = -0.0
z|1,7 = -0.0
x|1,8 = -0.0
r|1,8 = -0.0
z|1,8 = -0.0
x|1,9 = -0.0
r|1,9 = -0.0
z|1,9 = -0.0
x|1,10 = -0.0
r|1,10 = -0.0
z|1,10 = -0.0
x|1,11 = -0.0
r|1,11 = -0.0
z|1,11 = -0.0
x|2,0 = 1.0
r|2,0 = 0.0
z|2,0 = 4159.0
x|2,1 = -0.0
r|2,1 = -0.0
z|2,1 = -0.0
x|2,2 = 0.0
r|2,2 = -0.0
z|2,2 = -0.0
x|2,3 = -0.0
r|2,3 = -0.0
z|2,3 = -0.0
x|2,4 = -0.0
r|2,4 = -0.0
z|2,4 = -0.0
x|2,5 = -0.0
r|2,5 = -0.0
z|2,5 = -0.0
x|2,6 = -0.0
r|2,6 = -0.0
z|2,6 = -0.0
x|2,7 = -0.0
r|2,7 = -0.0
z|2,7 = -0.0
x|2,8 = -0.0
r|2,8 = -0.0
z|2,8 = -0.0
x|2,9 = -0.0
r|2,9 = -0.0
z|2,9 = -0.0
x|2,10 = -0.0
r|2,10 = -0.0
z|2,10 = -0.0
x|2,11 = -0.0
r|2,11 = -0.0
z|2,11 = -0.0
x|3,0 = 0.0
r|3,0 = 0.0
z|3,0 = -0.0
x|3,1 = -0.0
r|3,1 = -0.0
z|3,1 = -0.0
x|3,2 = -0.0
r|3,2 = -0.0
z|3,2 = -0.0
x|3,3 = 0.0
r|3,3 = -0.0
z|3,3 = -0.0
x|3,4 = -0.0
r|3,4 = -0.0
z|3,4 = -0.0
x|3,5 = -0.0
r|3,5 = -0.0
z|3,5 = -0.0
x|3,6 = -0.0
r|3,6 = -0.0
z|3,6 = -0.0
x|3,7 = -0.0
r|3,7 = -0.0
z|3,7 = -0.0
x|3,8 = 1.0
r|3,8 = 2590.0
z|3,8 = 2308.0
x|3,9 = -0.0
r|3,9 = -0.0
z|3,9 = -0.0
x|3,10 = -0.0
r|3,10 = -0.0
z|3,10 = -0.0
x|3,11 = -0.0
r|3,11 = -0.0
z|3,11 = -0.0
x|4,0 = 0.0
r|4,0 = 0.0
z|4,0 = -0.0
x|4,1 = -0.0
r|4,1 = -0.0
z|4,1 = -0.0
x|4,2 = -0.0
r|4,2 = -0.0
z|4,2 = -0.0
x|4,3 = -0.0
r|4,3 = -0.0
z|4,3 = -0.0
x|4,4 = 0.0
r|4,4 = -0.0
z|4,4 = -0.0
x|4,5 = -0.0
r|4,5 = -0.0
z|4,5 = -0.0
x|4,6 = -0.0
r|4,6 = -0.0
z|4,6 = -0.0
x|4,7 = -0.0
r|4,7 = -0.0
z|4,7 = -0.0
x|4,8 = -0.0
r|4,8 = -0.0
z|4,8 = -0.0
x|4,9 = 1.0
r|4,9 = 2729.0
z|4,9 = 2287.0
x|4,10 = -0.0
r|4,10 = -0.0
z|4,10 = -0.0
x|4,11 = -0.0
r|4,11 = -0.0
z|4,11 = -0.0
x|5,0 = 0.0
r|5,0 = 0.0
z|5,0 = -0.0
x|5,1 = -0.0
r|5,1 = -0.0
z|5,1 = -0.0
x|5,2 = -0.0
r|5,2 = -0.0
z|5,2 = -0.0
x|5,3 = -0.0
r|5,3 = -0.0
z|5,3 = -0.0
x|5,4 = -0.0
r|5,4 = -0.0
z|5,4 = -0.0
x|5,5 = 0.0
r|5,5 = -0.0
z|5,5 = -0.0
x|5,6 = -0.0
r|5,6 = -0.0
z|5,6 = -0.0
x|5,7 = -0.0
r|5,7 = -0.0
z|5,7 = -0.0
x|5,8 = -0.0
r|5,8 = -0.0
z|5,8 = -0.0
x|5,9 = -0.0
r|5,9 = -0.0
z|5,9 = -0.0
x|5,10 = -0.0
r|5,10 = -0.0
z|5,10 = -0.0
x|5,11 = 1.0
r|5,11 = 1961.0
z|5,11 = 2080.0
x|6,0 = 0.0
r|6,0 = 0.0
z|6,0 = -0.0
x|6,1 = -0.0
r|6,1 = -0.0
z|6,1 = -0.0
x|6,2 = -0.0
r|6,2 = -0.0
z|6,2 = -0.0
x|6,3 = -0.0
r|6,3 = -0.0
z|6,3 = -0.0
x|6,4 = 1.0
r|6,4 = 4183.0
z|6,4 = 1272.0
x|6,5 = -0.0
r|6,5 = -0.0
z|6,5 = -0.0
x|6,6 = 0.0
r|6,6 = -0.0
z|6,6 = -0.0
x|6,7 = -0.0
r|6,7 = -0.0
z|6,7 = -0.0
x|6,8 = -0.0
r|6,8 = -0.0
z|6,8 = -0.0
x|6,9 = -0.0
r|6,9 = -0.0
z|6,9 = -0.0
x|6,10 = -0.0
r|6,10 = -0.0
z|6,10 = -0.0
x|6,11 = -0.0
r|6,11 = -0.0
z|6,11 = -0.0
x|7,0 = 0.0
r|7,0 = 0.0
z|7,0 = -0.0
x|7,1 = -0.0
r|7,1 = -0.0
z|7,1 = -0.0
x|7,2 = -0.0
r|7,2 = -0.0
z|7,2 = -0.0
x|7,3 = -0.0
r|7,3 = -0.0
z|7,3 = -0.0
x|7,4 = -0.0
r|7,4 = -0.0
z|7,4 = -0.0
x|7,5 = 1.0
r|7,5 = 3552.0
z|7,5 = 1176.0
x|7,6 = -0.0
r|7,6 = -0.0
z|7,6 = -0.0
x|7,7 = 0.0
r|7,7 = -0.0
z|7,7 = -0.0
x|7,8 = -0.0
r|7,8 = -0.0
z|7,8 = -0.0
x|7,9 = -0.0
r|7,9 = -0.0
z|7,9 = -0.0
x|7,10 = -0.0
r|7,10 = -0.0
z|7,10 = -0.0
x|7,11 = -0.0
r|7,11 = -0.0
z|7,11 = -0.0
x|8,0 = 0.0
r|8,0 = 0.0
z|8,0 = -0.0
x|8,1 = -0.0
r|8,1 = -0.0
z|8,1 = -0.0
x|8,2 = 1.0
r|8,2 = 1371.0
z|8,2 = 3292.0
x|8,3 = -0.0
r|8,3 = -0.0
z|8,3 = -0.0
x|8,4 = -0.0
r|8,4 = -0.0
z|8,4 = -0.0
x|8,5 = -0.0
r|8,5 = -0.0
z|8,5 = -0.0
x|8,6 = -0.0
r|8,6 = -0.0
z|8,6 = -0.0
x|8,7 = -0.0
r|8,7 = -0.0
z|8,7 = -0.0
x|8,8 = 0.0
r|8,8 = -0.0
z|8,8 = -0.0
x|8,9 = -0.0
r|8,9 = -0.0
z|8,9 = -0.0
x|8,10 = -0.0
r|8,10 = -0.0
z|8,10 = -0.0
x|8,11 = -0.0
r|8,11 = -0.0
z|8,11 = -0.0
x|9,0 = 0.0
r|9,0 = 0.0
z|9,0 = -0.0
x|9,1 = -0.0
r|9,1 = -0.0
z|9,1 = -0.0
x|9,2 = -0.0
r|9,2 = -0.0
z|9,2 = -0.0
x|9,3 = -0.0
r|9,3 = -0.0
z|9,3 = -0.0
x|9,4 = -0.0
r|9,4 = -0.0
z|9,4 = -0.0
x|9,5 = -0.0
r|9,5 = -0.0
z|9,5 = -0.0
x|9,6 = -0.0
r|9,6 = -0.0
z|9,6 = -0.0
x|9,7 = -0.0
r|9,7 = -0.0
z|9,7 = -0.0
x|9,8 = -0.0
r|9,8 = -0.0
z|9,8 = -0.0
x|9,9 = 0.0
r|9,9 = -0.0
z|9,9 = -0.0
x|9,10 = 1.0
r|9,10 = 1716.0
z|9,10 = 3576.0
x|9,11 = -0.0
r|9,11 = -0.0
z|9,11 = -0.0
x|10,0 = 1.0
r|10,0 = 0.0
z|10,0 = 4549.0
x|10,1 = -0.0
r|10,1 = -0.0
z|10,1 = -0.0
x|10,2 = -0.0
r|10,2 = -0.0
z|10,2 = -0.0
x|10,3 = -0.0
r|10,3 = -0.0
z|10,3 = -0.0
x|10,4 = -0.0
r|10,4 = -0.0
z|10,4 = -0.0
x|10,5 = -0.0
r|10,5 = -0.0
z|10,5 = -0.0
x|10,6 = -0.0
r|10,6 = -0.0
z|10,6 = -0.0
x|10,7 = -0.0
r|10,7 = -0.0
z|10,7 = -0.0
x|10,8 = -0.0
r|10,8 = -0.0
z|10,8 = -0.0
x|10,9 = -0.0
r|10,9 = -0.0
z|10,9 = -0.0
x|10,10 = 0.0
r|10,10 = -0.0
z|10,10 = -0.0
x|10,11 = -0.0
r|10,11 = -0.0
z|10,11 = -0.0
x|11,0 = 1.0
r|11,0 = 0.0
z|11,0 = 3448.0
x|11,1 = -0.0
r|11,1 = -0.0
z|11,1 = -0.0
x|11,2 = -0.0
r|11,2 = -0.0
z|11,2 = -0.0
x|11,3 = -0.0
r|11,3 = -0.0
z|11,3 = -0.0
x|11,4 = -0.0
r|11,4 = -0.0
z|11,4 = -0.0
x|11,5 = -0.0
r|11,5 = -0.0
z|11,5 = -0.0
x|11,6 = -0.0
r|11,6 = -0.0
z|11,6 = -0.0
x|11,7 = -0.0
r|11,7 = -0.0
z|11,7 = -0.0
x|11,8 = -0.0
r|11,8 = -0.0
z|11,8 = -0.0
x|11,9 = -0.0
r|11,9 = -0.0
z|11,9 = -0.0
x|11,10 = -0.0
r|11,10 = -0.0
z|11,10 = -0.0
x|11,11 = 0.0
r|11,11 = -0.0
z|11,11 = -0.0
In [19]:
pt = vm.get_path(m)
[(0, 0)]
[(0, 1), (1, 3), (3, 8), (8, 2), (2, 0)]
[(0, 6), (6, 4), (4, 9), (9, 10), (10, 0)]
[(0, 7), (7, 5), (5, 11), (11, 0)]
In [20]:
routes = vm.get_GISpath(graph, pt, customers)

route map of all the vehicles

In [21]:
vm.plot_all_route(graph, customers, routes)

route map of vehicle 1

In [22]:
vm.plot_single_route(graph, customers, routes[1])

route map of vehicle 2

In [23]:
vm.plot_single_route(graph, customers, routes[2])

route map of vehicle 3

In [24]:
vm.plot_single_route(graph, customers, routes[3])

route map of vehicle 4

In [26]:
#vm.plot_single_route(graph, customers, routes[4])
In [27]:
    vR = {}
    for v in m.getVars():
        if(v.x > 1):
            # print(v.name, " = ", v.varValue)
            temp = (v.varName.split('|')[1]).split(',')
            #print(temp[0],",", temp[1])
            vR[v.varName] = round(v.x,2)
            #print(v.varName, "=", v.x)

Pick up and deliver amount for each vehicle here r represents delivery amount, z represents pickup amount.

In [28]:
vR
Out[28]:
{'r|0,1': 5900.0,
 'r|0,6': 5346.0,
 'r|0,7': 5043.0,
 'r|1,3': 4349.0,
 'z|1,3': 866.0,
 'z|2,0': 4159.0,
 'r|3,8': 2590.0,
 'z|3,8': 2308.0,
 'r|4,9': 2729.0,
 'z|4,9': 2287.0,
 'r|5,11': 1961.0,
 'z|5,11': 2080.0,
 'r|6,4': 4183.0,
 'z|6,4': 1272.0,
 'r|7,5': 3552.0,
 'z|7,5': 1176.0,
 'r|8,2': 1371.0,
 'z|8,2': 3292.0,
 'r|9,10': 1716.0,
 'z|9,10': 3576.0,
 'z|10,0': 4549.0,
 'z|11,0': 3448.0}
In [ ]: